package com.tanhua.app.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.api.service.CommentApi;
import com.tanhua.api.service.MovementApi;
import com.tanhua.api.service.UserInfoApi;
import com.tanhua.app.Interceptor.UserHolder;
import com.tanhua.app.exception.BusinessException;
import com.tanhua.commons.utils.Constants;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.CommentVo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class CommentService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @DubboReference
    private CommentApi commentApi;

    @DubboReference
    private MovementApi movementApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    // 发布评论
    public void saveComment(String movementId, String comment) {

        // 获取当前用户id
        Long userId = UserHolder.getUserId();

        // 根据动态id查询动态数据
        Movement movement = movementApi.findById(movementId);

        // 判断动态数据是否为空
        if (movement == null || StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }

        // 补全参数
        Comment newComment = new Comment();
        newComment.setCommentType(CommentType.COMMENT.getType());
        newComment.setContent(comment);
        newComment.setCreated(System.currentTimeMillis());
        newComment.setUserId(userId);
        newComment.setPublishId(new ObjectId(movementId));
        // 被评论人的id
        newComment.setPublishUserId(movement.getUserId());

        Integer commentCount = commentApi.saveComment(newComment);
    }

    // 分页查询品论列表
    public PageResult<CommentVo> findPageComment(Integer page, Integer pagesize, String movementId) {

        // 查询评论列表
        List<Comment> commentList =
                commentApi.findPageComment(page, pagesize, movementId);

        // 判断是否有评论
        if (CollUtil.isEmpty(commentList)) {
            return new PageResult<>();
        }

        // 抽取用户id
        List<Long> ids = commentList.stream().map(Comment::getUserId).collect(Collectors.toList());

        // 根据用户列表查询用户详情数据
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids).stream()
                .collect(Collectors.toMap(UserInfo::getId, Function.identity()));

        // 分装数据
        List<CommentVo> list = new ArrayList<>();
        for (Comment comment : commentList) {
            CommentVo commentVo = CommentVo.init(map.get(comment.getUserId()), comment);

            list.add(commentVo);
        }

        return new PageResult<>(page, pagesize, 0, list);
    }

    // 评论点赞
    public Integer likeComment(String movementId) {

        // 判断用户是否异将点赞
        Boolean hasComment = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LIKE);

        if (hasComment) {
            throw new BusinessException(ErrorResult.likeError());
        }

        // 根据动态Id查询动态数据
        Movement movement = movementApi.findById(movementId);
        if (movement == null || StringUtils.isBlank(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }

        // 分装数据
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setUserId(UserHolder.getUserId());
        comment.setCreated(System.currentTimeMillis());

        comment.setPublishUserId(movement.getUserId());

        Integer count = commentApi.saveComment(comment);

        // 将当前用户点赞的记录，保存到redis中
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().put(key, hashKey, "1");

        return count;
    }


    // 取消评论点赞
    public Integer dislikeComment(String movementId) {

        // 判断用户是否已经点赞
        Boolean hasComment = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LIKE);

        if (!hasComment) {
            // 条件成立表示，评论没有点赞
            throw new BusinessException(ErrorResult.disLikeError());
        }

        // 删除数据
        Comment comment = new Comment();
        comment.setUserId(UserHolder.getUserId());
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setPublishId(new ObjectId(movementId));

        Integer likeCount = commentApi.remove(comment);

        // 删除reids中的点赞数据
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().delete(key, hashKey);

        return likeCount;

    }

    // 动态喜欢
    public Integer loveComment(String movementId) {

        // 获取是否已经喜欢
        Boolean hasComment = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LOVE);

        if (hasComment) {
            throw new BusinessException(ErrorResult.loveError());
        }

        // 根据动态id,查询动态数
        Movement movement = movementApi.findById(movementId);

        if (movement == null || StringUtils.isBlank(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }

        // 分装数据
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setPublishUserId(movement.getUserId());
        comment.setCreated(System.currentTimeMillis());
        comment.setUserId(UserHolder.getUserId());

        Integer loveCount = commentApi.saveComment(comment);

        // 将喜欢的标记到redis中
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().put(key, hashKey, "1");

        return loveCount;

    }

    // 取消动态喜欢
    public Integer unloveComment(String movementId) {

        // 判断是否喜欢
        Boolean hasComment = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LOVE);

        if (!hasComment) {
            // 表示，评论没有被喜欢了
            throw new BusinessException(ErrorResult.disloveError());
        }

        // 封装数据
        Comment comment = new Comment();
        comment.setUserId(UserHolder.getUserId());
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(CommentType.LOVE.getType());

        Integer loveCount = commentApi.remove(comment);

        // 删除redis中的记录
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().delete(key, hashKey);

        return loveCount;

    }
}
